package org.scohen.juploadr.app.geo;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Text;
import org.scohen.juploadr.Messages;
import org.scohen.juploadr.app.ImageAttributes;
import org.scohen.juploadr.uploadapi.ImageUploadApi;
import org.scohen.juploadr.uploadapi.abilities.Abilities;
import org.scohen.juploadr.uploadapi.abilities.GeoAbilities;

import au.com.lastweekend.jim.util.StringUtils;

public class GeoTab extends Composite {
    private Text txtLatitude;
    private Text txtLongitude;
    private Text txtName;
    private Combo comboPrivacy;
    private Scale accuracy;
    private Combo comboLocations;
    private GeoTabEventHandler handler;
    private Button buttonCreate;
    private Button buttonClear;
    private Button buttonLookup;
    private Button buttonDelete;
    private GeoLocation location;
    private Text geoCodeLocation;
    private Label labelAccuracy;

    public GeoTab(Composite mainForm, ImageAttributes atts) {
        super(mainForm, SWT.NONE);
        this.location = atts.getLocation();
        handler = new GeoTabEventHandler();
        initUI();
        setCurrentLocation(atts.getLocation());

    }

    public void resetData(ImageAttributes newAtts) {
        location = newAtts.getLocation();
        GeoAbilities geo = ImageUploadApi.getInstance().getAbilities().getGeoAbilities();
        if (labelAccuracy != null) {
            accuracy.setSelection(((geo.getMaxAccuracy() - geo.getMinAccuracy()) / 2) + 1);
            labelAccuracy.setText(geo.getAccuracyLabels()[accuracy.getSelection()]);
        }
        if (geo.hasGeoAbilities()) {
            comboLocations.select(0);
            int i = 0;
            String[] items = comboLocations.getItems();
            for (String item : items) {
                if (location != null && item.equals(location.getName())) {
                    comboLocations.select(i);
                    break;
                }
                i++;
            }
            if (location != null) {
                if (location.getName() != null) {
                    txtName.setText(location.getName());
                }
                txtLatitude.setText(String.valueOf(location.getLatitude()));
                txtLongitude.setText(String.valueOf(location.getLongitude()));
            } else {
                txtName.setText("");
                txtLatitude.setText("");
                txtLongitude.setText("");
            }
        }
    }

    private void initUI() {
        GeoAbilities geo = ImageUploadApi.getInstance().getAbilities().getGeoAbilities();

        if (geo.hasGeoAbilities()) {

            GridLayout layout = new GridLayout(2, true);
            layout.numColumns = 2;
            layout.makeColumnsEqualWidth = false;
            setLayout(layout);
            setLayoutData(new GridData(GridData.FILL_BOTH));

            new Label(this, SWT.NONE).setText("Find Location");
            Composite lookup = new Composite(this, SWT.NONE);
            lookup.setLayout(new GridLayout(2, false));
            lookup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            geoCodeLocation = new Text(lookup, SWT.SINGLE | SWT.BORDER);
            geoCodeLocation.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            buttonLookup = new Button(lookup, SWT.PUSH);
            buttonLookup.setText("Look Up");
            buttonLookup.addSelectionListener(handler);

            new Label(this, SWT.NONE).setText("Location");
            Composite c = new Composite(this, SWT.NONE);
            c.setLayout(new GridLayout(2, false));
            c.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            comboLocations = new Combo(c, SWT.READ_ONLY | SWT.DROP_DOWN);
            comboLocations.add(Messages.getString("juploadr.ui.label.none"));
            int i = 1;
            comboLocations.select(0);
            for (GeoLocation g : geo.getLocations().values()) {
                comboLocations.add(g.getName());
                comboLocations.setData(g.getName(), g);
                if (location != null && g.getName().equals(location.getName())) {
                    comboLocations.select(i);
                }
                i++;
            }
            comboLocations.addSelectionListener(handler);
            comboLocations.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

            buttonDelete = new Button(c, SWT.PUSH);
            buttonDelete.setText("Delete");
            buttonDelete.addSelectionListener(handler);

            new Label(this, SWT.NONE).setText("Name");
            txtName = new Text(this, SWT.SINGLE | SWT.BORDER);
            txtName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            new Label(this, SWT.NONE).setText("Latitude");
            txtLatitude = new Text(this, SWT.SINGLE | SWT.BORDER);
            txtLatitude.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

            new Label(this, SWT.NONE).setText("Longitude");
            txtLongitude = new Text(this, SWT.SINGLE | SWT.BORDER);
            txtLongitude.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

            if (geo.hasAccuracy()) {
                new Label(this, SWT.NONE).setText("Accuracy");
                accuracy = new Scale(this, SWT.HORIZONTAL);
                accuracy.setMinimum(geo.getMinAccuracy());
                accuracy.setMaximum(geo.getMaxAccuracy());
                accuracy.setToolTipText("Accuracy");
                accuracy.setPageIncrement(1);
                accuracy.setIncrement(1);
                accuracy.setSelection(((geo.getMaxAccuracy() - geo.getMinAccuracy()) / 2) + 1);
                accuracy.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                accuracy.addSelectionListener(handler);
                new Label(this, SWT.NONE);
                labelAccuracy = new Label(this, SWT.NONE);
                labelAccuracy.setText(geo.getAccuracyLabels()[accuracy.getSelection()]);
                labelAccuracy.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            }
            Composite buttons = new Composite(this, SWT.NONE);
            GridData d = new GridData();
            d.grabExcessHorizontalSpace = true;
            d.horizontalSpan = 2;
            d.horizontalAlignment = GridData.END;
            buttons.setLayoutData(d);
            buttons.setLayout(new FillLayout());
            buttonCreate = new Button(buttons, SWT.PUSH);
            buttonCreate.setText("Create/Update Location");
            buttonCreate.addSelectionListener(handler);
            // buttonClear = new Button(buttons, SWT.PUSH);
            // buttonClear.setText("Clear");
            // buttonClear.addSelectionListener(handler);

        }
        setSize(computeSize(SWT.DEFAULT, SWT.DEFAULT));
    }

    public GeoLocation getGeoLocation() {
        return location;
    }

    private void setCurrentLocation(GeoLocation loc) {
        location = loc;
        if (loc != null) {
            if (loc.getName() != null) {
                txtName.setText(loc.getName());
            }
            txtLatitude.setText(String.valueOf(loc.getLatitude()));
            txtLongitude.setText(String.valueOf(loc.getLongitude()));
            if (ImageUploadApi.getInstance().getAbilities().getGeoAbilities().hasAccuracy()) {
                accuracy.setSelection(loc.getAccuracy());
            }
        }
    }

    private class GeoTabEventHandler implements SelectionListener {

        public void widgetDefaultSelected(SelectionEvent event) {
            // TODO Auto-generated method stub

        }

        public void widgetSelected(SelectionEvent event) {
            GeoAbilities geo = ImageUploadApi.getInstance().getAbilities().getGeoAbilities();
            if (event.widget == comboLocations) {
                // find it!
                String selectedLocationName = comboLocations.getItem(comboLocations.getSelectionIndex());
                if ("None".equalsIgnoreCase(selectedLocationName)) {
                    txtName.setText("");
                    txtLatitude.setText("");
                    txtLongitude.setText("");
                    accuracy.setSelection(((geo.getMaxAccuracy() - geo.getMinAccuracy()) / 2) + 1);
                    location = null;
                } else {
                    setCurrentLocation(geo.getLocations().get(selectedLocationName));
                }
            } else if (event.widget == buttonCreate) {

                GeoLocation toAdd = geo.getLocations().get(txtName.getText());
                if (toAdd == null) {
                    toAdd = new GeoLocation(txtName.getText(), Double.valueOf(txtLatitude.getText()), Double
                            .valueOf(txtLongitude.getText()));
                    comboLocations.add(toAdd.getName());
                    comboLocations.setData(toAdd.getName(), toAdd);
                }
                if (geo.hasAccuracy()) {
                    toAdd.setAccuracy(accuracy.getSelection());
                }
                geo.addLocation(toAdd);

            } else if (event.widget == buttonLookup) {
                System.out.println("look up");
                String location = geoCodeLocation.getText();
                GeoLocation l = GeoCoderFactory.getInstance().geoCode("", location);
                if (l != null) {
                    setCurrentLocation(l);
                }
            } else if (event.widget == buttonDelete) {
                GeoLocation loc = (GeoLocation) comboLocations.getData(comboLocations.getItem(comboLocations
                        .getSelectionIndex()));
                if (loc != null) {
                    comboLocations.remove(loc.getName());
                    geo.removeLocation(loc);
                }
            } else if (event.widget == accuracy) {
                labelAccuracy.setText(accuracy.getSelection() + " ("
                        + geo.getAccuracyLabels()[accuracy.getSelection()] + ")");
            }
        }

    }
}
